package com.haiqiu.tools.test.controller;

import com.haiqiu.file.constant.Constants;
import com.haiqiu.file.local.config.LocalConfig;
import com.haiqiu.file.local.utils.FileServer;
import com.haiqiu.file.local.utils.ServerFileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;

/**
 * @author HaiQiu
 * @since 2023/3/8
 * 本地文件上传测试
 */
@RestController
@RequestMapping("/server")
public class ServerFileController {

    public static final String PATH = "/test/document";

    @Autowired
    private LocalConfig localConfig;

    /**
     * linux默认分割符号
     */
    private static final String DELETE_LINUX_PATH = "/";


    /**
     * 添加一个资源映射，系统才能正常访问资源文件
     */
    @Component
    public class WebResource implements WebMvcConfigurer {
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            //获取路径分隔符
            String symbol = getLocalOs().equals(Constants.WINDOWS) ? "\\" : "/";
            String folder = localConfig.getParent().equals(DELETE_LINUX_PATH) ? localConfig.getParent() : localConfig.getParent() + symbol;
            //其中fictitious表示访问的前缀。"file:F:/img/"是文件真实的存储路径
            registry.addResourceHandler(localConfig.getVirtual() + "/**").addResourceLocations("file:" + folder);
        }
    }

    /**
     * 单文件上传
     *
     * @param file 文件
     */
    @PostMapping(value = "upload")
    public Object uploads(@RequestParam("file") MultipartFile file) {
        String filePath = ServerFileUtils.upload("/test/document", file);
        if (filePath != null) {
            System.out.println("文件：" + file.getOriginalFilename() + "上传成功,服务器路径：" + filePath);
        }
        return filePath;
    }

    /**
     * 多文件上传
     *
     * @param files 文件批量上传
     */
    @PostMapping(value = "uploads")
    public Object uploads(@RequestPart(value = "files") List<MultipartFile> files) {
        Set<String> filePaths = new HashSet<>();
        for (MultipartFile file : files) {
            String filePath = ServerFileUtils.upload(PATH, file);
            if (filePath != null) {
                System.out.println("文件：" + file.getOriginalFilename() + "上传成功,服务器路径：" + filePath);
                filePaths.add(filePath);
            }
        }
        return filePaths;
    }

    /**
     * 单文件下载
     * 此接口可以预览图片，文档，文本等常见的文件浏览器打开预览
     *
     * @param fileName 文件
     */
    @GetMapping(value = "download/{fileName}")
    public void download(@PathVariable("fileName") String fileName) {
        String remoteFilePath = PATH + "/" + fileName;
        ServerFileUtils.download(remoteFilePath);
    }

    /**
     * 单文件下载
     * 返回文件二进制流
     *
     * @param fileName 文件
     */
    @GetMapping(value = "downloadFile/{fileName}")
    public void downloadFile(@PathVariable("fileName") String fileName) {
        String remoteFilePath = PATH + "/" + fileName;
        ServerFileUtils.download(remoteFilePath);
    }


    /**
     * 查看本地集合列表
     *
     * @param path 路径前缀
     * @return 集合信息
     */
    @GetMapping(value = "list")
    public List<FileServer> list(String path) {
        return ServerFileUtils.getFiles(path, null, null);
    }


    /**
     * 删除本地文件
     *
     * @param remotePath 文件地址
     * @return 删除成功
     */
    @DeleteMapping
    public boolean delete(@RequestParam String remotePath) {
        return ServerFileUtils.deleteFile(remotePath);
    }

    /**
     * 获取本机的操作系统
     *
     * @return 操作系统
     */
    public static String getLocalOs() {
        //系统属性
        Properties props = System.getProperties();
        //System.out.println("操作系统的名称：" + props.getProperty("os.name"));
        String os = props.getProperty("os.name");
        if (os.contains(Constants.WINDOWS)) {
            return Constants.WINDOWS;
        } else {
            return Constants.LINUX;
        }
    }
}
